package com.tre.jdevtemplateboot.exception.global;

import com.tre.jdevtemplateboot.common.dto.ParamValidate;
import com.tre.jdevtemplateboot.common.dto.ResponseResult;
import com.tre.jdevtemplateboot.common.enums.ErrorLogEnums;
import com.tre.jdevtemplateboot.common.enums.ExceptionHandlerEnums;
import com.tre.jdevtemplateboot.exception.business.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;


/**
 * @author jdev
 */
@RestControllerAdvice
public class GlobalControllerExceptionHandler {

    private static final Logger LOGGER = LoggerFactory.getLogger(GlobalControllerExceptionHandler.class);
    private static final String ERROR_MESSAGE_PRE = "请求的url为{}出现{}异常,异常信息为:";

    @ExceptionHandler(value = {HttpRequestMethodNotSupportedException.class})
    public ResponseResult requestMethodNotSupportedException(HttpServletRequest request, HttpRequestMethodNotSupportedException ex) {
        LOGGER.error(ERROR_MESSAGE_PRE, request.getRequestURI(), ErrorLogEnums.REQUEST_METHOD.getMessage(), ex);
        return ResponseResult.buildError(405,500,ErrorLogEnums.REQUEST_METHOD.getMessage());
    }

    @ExceptionHandler(value = {SysInvalidTokenException.class, SysUnAuthorizedException.class,
            SysUnAuthenticatedException.class, SysUnAuthorizedFileException.class, SysInvalidUserException.class})
    @ResponseStatus(HttpStatus.UNAUTHORIZED)
    public ResponseResult sysInvalidTokenException(HttpServletRequest request, SysBusinessException ex) {
        LOGGER.error(ERROR_MESSAGE_PRE, request.getRequestURI(), ErrorLogEnums.SERVER_ERROR.getMessage(), ex);
        return ResponseResult.buildError(ex);
    }

    @ExceptionHandler(value = {SysBusinessException.class})
    public ResponseResult sysException(HttpServletRequest request, SysBusinessException ex) {
        LOGGER.error(ERROR_MESSAGE_PRE, request.getRequestURI(), ErrorLogEnums.SERVER_ERROR.getMessage(), ex);
        return ResponseResult.buildError(ex);
    }

    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResponseResult parameterExceptionHandler(HttpServletRequest request, MethodArgumentNotValidException ex) {
        LOGGER.error(ERROR_MESSAGE_PRE, request.getRequestURI(),ErrorLogEnums.PARAM_ERROR.getMessage(), ex);
        BindingResult bindingResult = ex.getBindingResult();
        List<ParamValidate> errorMsgList = null;
        if (bindingResult.hasErrors()) {
            errorMsgList = new ArrayList();
            for (FieldError fieldError : bindingResult.getFieldErrors()) {
                errorMsgList.add(new ParamValidate(fieldError.getField(),fieldError.getDefaultMessage()));
            }
        }
        return  ResponseResult.buildError(ExceptionHandlerEnums.PARAM_VALIDATE_ERROR.getStatus(),
                ExceptionHandlerEnums.PARAM_VALIDATE_ERROR.getMsg(),errorMsgList);
    }

    @ExceptionHandler(Exception.class)
    public ResponseResult exceptionHandler(HttpServletRequest request, Exception ex){
        LOGGER.error(ERROR_MESSAGE_PRE, request.getRequestURI(), ErrorLogEnums.SERVER_ERROR.getMessage(), ex);
        return ResponseResult.buildError();
    }

}
